package com.time;

import org.apache.http.client.utils.DateUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class DateTimeUtils {

    /**
     * 获取当前月份
     * @return yyyy-mm-dd
     */
    public static String getCurrentDateMonth(){
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM");
        Date date = new Date();
        return f.format(date);
    }


    /**
     * 获取当前时间
     * @return yyyy-mm-dd hh:mm:ss
     */
    public static String getCurrentTime(){
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date();
        return f.format(date);
    }
    /**
     * 获取当前日期
     * @return yyyy-mm-dd
     */
    public static String getCurrentDate(){
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        return f.format(date);
    }


    /**
     * 获取当下的年份
     * @return
     */
    public static String getCurentYear(){
        SimpleDateFormat formatter= new SimpleDateFormat("yyyy");
        Date date = new Date(System.currentTimeMillis());
        return formatter.format(date);
    }


    /**
     *
     * @param days 正数表示该日期后n天，负数表示该日期的前n天
     * @return
     */
    public static String getCurrentbfDays(int days){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();
        //过去七天
        c.setTime(new Date());
        c.add(Calendar.DATE, days);
        Date d = c.getTime();
        String day = format.format(d);
        return day;
    }

    /**
     *
     * @param dateStr 指定日期
     * @param days 正数表示该日期后n天，负数表示该日期的前n天
     * @return
     */
    public static  String getDateBfDays(String dateStr,int days){
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        // 将字符串的日期转为Date类型，ParsePosition(0)表示从第一个字符开始解析
        Date date = dateFormat.parse(dateStr, new ParsePosition(0));
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // add方法中的第二个参数n中，正数表示该日期后n天，负数表示该日期的前n天
        calendar.add(Calendar.DATE, days);
        Date date1 = calendar.getTime();
        String out = dateFormat.format(date1);
        return out;
    }


    /**
     * 获取某年最后一天日期
     * @param year 年份
     * @return Date
     */
    public static String getYearLastDay(int year){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearLast = calendar.getTime();
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        return f.format(currYearLast);
    }

    /**
     * 获取某季度的第一天和最后一天
     *	@param num 第几季度
     */
    public static String[] getCurrQuarter(int num) {
        String[] s = new String[2];
        String str = "";
        // 设置本年的季
        Calendar quarterCalendar = null;
        switch (num) {
            case 1: // 本年到现在经过了一个季度，在加上前4个季度
                quarterCalendar = Calendar.getInstance();
                quarterCalendar.set(Calendar.MONTH, 3);
                quarterCalendar.set(Calendar.DATE, 1);
                quarterCalendar.add(Calendar.DATE, -1);
                str = DateUtils.formatDate(quarterCalendar.getTime(), "yyyy-MM-dd");
                s[0] = str.substring(0, str.length() - 5) + "01-01";
                s[1] = str;
                break;
            case 2: // 本年到现在经过了二个季度，在加上前三个季度
                quarterCalendar = Calendar.getInstance();
                quarterCalendar.set(Calendar.MONTH, 6);
                quarterCalendar.set(Calendar.DATE, 1);
                quarterCalendar.add(Calendar.DATE, -1);
                str = DateUtils.formatDate(quarterCalendar.getTime(), "yyyy-MM-dd");
                s[0] = str.substring(0, str.length() - 5) + "04-01";
                s[1] = str;
                break;
            case 3:// 本年到现在经过了三个季度，在加上前二个季度
                quarterCalendar = Calendar.getInstance();
                quarterCalendar.set(Calendar.MONTH, 9);
                quarterCalendar.set(Calendar.DATE, 1);
                quarterCalendar.add(Calendar.DATE, -1);
                str = DateUtils.formatDate(quarterCalendar.getTime(), "yyyy-MM-dd");
                s[0] = str.substring(0, str.length() - 5) + "07-01";
                s[1] = str;
                break;
            case 4:// 本年到现在经过了四个季度，在加上前一个季度
                quarterCalendar = Calendar.getInstance();
                str = DateUtils.formatDate(quarterCalendar.getTime(), "yyyy-MM-dd");
                s[0] = str.substring(0, str.length() - 5) + "10-01";
                s[1] = str.substring(0, str.length() - 5) + "12-31";
                break;
        }
        return s;
    }

    /**
     * 获取当前季度
     *
     */
    public static  int getQuarter() {
        Calendar c = Calendar.getInstance();
        int month = c.get(c.MONTH) + 1;
        int quarter = 0;
        if (month >= 1 && month <= 3) {
            quarter = 1;
        } else if (month >= 4 && month <= 6) {
            quarter = 2;
        } else if (month >= 7 && month <= 9) {
            quarter = 3;
        } else {
            quarter = 4;
        }
        return quarter;
    }



    /**
     * 获取当月的最后一天
     * @return
     */
    public static String currentMonthLastDay(){
        //设置时间格式
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//获得实体类
        Calendar ca = Calendar.getInstance();
//设置最后一天
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
//最后一天格式化
        String lastDay = format.format(ca.getTime());
        return lastDay;
    }

    /**
     * 获取当前半年的最后一天
     * @return
     * @throws Exception
     */
    public static String getHalfYearEndTime() throws Exception{
        SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        try {
            if (currentMonth >= 1 && currentMonth <= 6){
                c.set(Calendar.MONTH, 5);
                c.set(Calendar.DATE, 30);
            }else if (currentMonth >= 7 && currentMonth <= 12){
                c.set(Calendar.MONTH, 11);
                c.set(Calendar.DATE, 31);
            }
            return shortSdf.format(c.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     *
     * 判断当前月份是上半年 还是下半年
     * @return  1--上半年 2--下半年
     * @throws Exception
     */
    public static int  getHalfYearFlag(){
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        System.out.printf(currentMonth+"\n");
        try {
            if (currentMonth >= 1 && currentMonth <= 6){
                return 1;
            }else if (currentMonth >= 7 && currentMonth <= 12){
                return 2;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;

    }

    /**
     * 判日期是否在日期段内(不包含前后日期)
     *
     * @param nowTimeStr
     * @param beginTimeStr
     * @param endTimeStr
     * @return true --在时间范围内 ，false--不在时间周期内
     */
    public static boolean belongDateCalendar(String nowTimeStr,String beginTimeStr,String endTimeStr)throws Exception {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date nowTime=df.parse(nowTimeStr);
        Date beginTime=df.parse(beginTimeStr);
        Date endTime=df.parse(endTimeStr);
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);
        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);
        Calendar end = Calendar.getInstance();
        end.setTime(endTime);
        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 判日期是否在日期段内(包含前后日期)
     *
     * @param nowTimeStr
     * @param beginTimeStr
     * @param endTimeStr
     * @return true --在时间范围内 ，false--不在时间周期内
     */
    public static  boolean belongDatetimeStamp(String nowTimeStr,String beginTimeStr,String endTimeStr)throws Exception{
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Long nowTime=df.parse(nowTimeStr).getTime();
        Long beginTime=df.parse(beginTimeStr).getTime();
        Long endTime=df.parse(endTimeStr).getTime();
        System.out.printf(nowTime+"\n");
        System.out.printf(beginTime+"\n");
        System.out.printf(endTime+"\n");
        if (nowTime>beginTime&&nowTime<endTime){
            return true;
        }else if (nowTime.equals(beginTime)|| nowTime.equals(endTime)){
            return true;
        }else {
            return false;
        }
    }


    /**
     *计算两个日期之间相差的天数
     * @param beginDate
     * @param endDate
     * @return
     */
    public static int differDaysDate(String beginDate,String endDate)throws Exception{
        SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date fromDate1 = simpleFormat.parse(beginDate);
        Date toDate1 = simpleFormat.parse(endDate);
        long from1 = fromDate1.getTime();
        long to1 = toDate1.getTime();
        int days = (int) ((to1 - from1) / (1000 * 60 * 60 * 24));
        return days;
    }

    /**
     * 指定日期增加月数
     * @param date 日期
     * @param months 月数
     * @return
     */
    public static String addDateMonths(String date,int months){
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        Calendar cd=Calendar.getInstance();//获取一个Calendar对象
        try{
            cd.setTime(sdf.parse(date));//设置calendar日期
        }catch(ParseException e){
            e.printStackTrace();
        }

        cd.add(Calendar.MONTH,months);//增加n个月
        return sdf.format(cd.getTime());
    }

    /**
     * 获取n个月前的第一天
     * @param n
     * @return
     */
    public static String getAppointMonths(int n){
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        Calendar cd=Calendar.getInstance();//获取一个Calendar对象
        cd.add(Calendar.MONTH, -n);//设置calendar日期
        cd.set(Calendar.DAY_OF_MONTH,1);//设置为1号
        String fristDate = sdf.format(cd.getTime());
        return fristDate;
    }

    /**
     * 获取当前时间
     * @return yyyy-MM-dd HH:mm:ss
     */
    public static String getCurrentTimeByFormat(String format){
        SimpleDateFormat f = new SimpleDateFormat(format);
        Date date = new Date();
        return f.format(date);
    }

    /**

     * 根据年 月 获取对应的月份 天数

     * */

    public static int getDaysByYearMonth(String date) {
         String[] dateSz = date.split("-");
         int year=Integer.parseInt(dateSz[0]);
        int month=Integer.parseInt(dateSz[1]);
        Calendar a = Calendar.getInstance();

        a.set(Calendar.YEAR, year);

        a.set(Calendar.MONTH, month - 1);

        a.set(Calendar.DATE, 1);

        a.roll(Calendar.DATE, -1);

        int maxDate = a.get(Calendar.DATE);

        return maxDate;

    }


    /**
     * 相差几个月
     * @param startDate
     * @param endDate
     * @return
     * @throws ParseException
     */
    public static long getMonthDiff(String startDate, String endDate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

            int result=0;
            Calendar cal1 = new GregorianCalendar();
            cal1.setTime(sdf.parse(startDate));
        Calendar cal2 = new GregorianCalendar();
            cal2.setTime(sdf.parse(endDate));
        result =(cal1.get(Calendar.YEAR) - cal2.get(Calendar.YEAR)) * 12 + cal1.get(Calendar.MONTH)- cal2.get(Calendar.MONTH);
            return result==0?0 : Math.abs(result);

    }


    /**
     * 计算两个日期相差月数和天数
     * @param startDate
     * @param endDate
     * @return
     */
     public  static int[] getDiff(String startDate, String endDate) {
         DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate start = LocalDate.parse(startDate,df);
        LocalDate end = LocalDate.parse(endDate,df);

        if (startDate.equals(endDate)){
            return new int[] {0, 0};
        }

        if (!start.isBefore(end)) {
            throw new IllegalArgumentException("Start must not be before end.");
        }

        Period period = Period.between(start, end);

        int years = period.getYears();
        int months = period.getMonths();
        int days = period.getDays();

        return new int[] {years * 12 + months, days};
    }

    /**
     * 获取当前季度后一个月指定的日期
     * @param loanDate 贷款日期
     * @param day
     * @return
     */
    public static String getLoanQuarterDay(String loanDate,int day){
        String[] loanDateSz=loanDate.split("-");
        String yearStr=loanDateSz[0];
        String monthStr=loanDateSz[1];
        int monthIn=Integer.parseInt(monthStr);
        String quarterDate="";
        String dayStr="";
        if (day<10){
            dayStr="0"+day;
        }else {
            dayStr=String.valueOf(day);
        }
        if (monthIn >= 1 && monthIn <= 3) {
            quarterDate=yearStr+"-03-"+dayStr;
        } else if (monthIn >= 4 && monthIn <= 6) {
            quarterDate=yearStr+"-06-"+dayStr;
        } else if (monthIn >= 7 && monthIn <= 9) {
            quarterDate=yearStr+"-09-"+dayStr;
        } else {
            quarterDate=yearStr+"-12-"+dayStr;
        }

        return quarterDate;
    }

    /**
     * 获取当前季度后一个月指定的日期
     * @param day
     * @return
     */
    public static String getCurrentQuarterDay(int day){
        int quarter= getQuarter();
        String currentYear=getCurentYear();
        String quarterDate="";
        String dayStr="";
        if (day<10){
            dayStr="0"+day;
        }else {
            dayStr=String.valueOf(day);
        }
        switch (quarter){
            case 1:
                quarterDate=currentYear+"-03-"+dayStr;
                break;
            case 2:
                quarterDate=currentYear+"-06-"+dayStr;
                break;
            case 3:
                quarterDate=currentYear+"-09-"+dayStr;
                break;
            case 4:
                quarterDate=currentYear+"-12-"+dayStr;
                break;
        }
        return quarterDate;
    }

    /**
     * 判断两个日期大小
     * @param time1
     * @param time2
     * @return true time1小于time2,否则大于
     * @throws ParseException
     */
    public static boolean compare(String time1,String time2) throws ParseException
    {
        //如果想比较日期则写成"yyyy-MM-dd"就可以了
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        //将字符串形式的时间转化为Date类型的时间
        Date a=sdf.parse(time1);
        Date b=sdf.parse(time2);
        //Date类的一个方法，如果a早于b返回true，否则返回false
        if(a.before(b)) {
            return true;
        }else {
            return false;
        }
		/*
		 * 如果你不喜欢用上面这个太流氓的方法，也可以根据将Date转换成毫秒
		if(a.getTime()-b.getTime()<0)
			return true;
		else
			return false;
		*/
    }

    /**
     * 获取之前指定的年份
     * @return
     */
    public static  String lastYear(int years){
        SimpleDateFormat formats = new SimpleDateFormat("yyyy");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.YEAR,years);
        Date date =  c.getTime();
        System.out.println(formats.format(date));
        return formats.format(date);
    }

    /**
     * 根据指定日期获取n年后的年份
     * @param time
     * @param n （由0开始，0表示当年，后续依次往后推，1为1年后，2为两两后，。。。）
     * @return
     */
    public static String getAppointYear(Date time, int n){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat formats = new SimpleDateFormat("yyyy");
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        c.add(Calendar.YEAR,n);
        Date date = c.getTime();
        System.out.println(formats.format(date));
        return formats.format(date);
    }

    public static void main(String[] args)throws Exception {


//        lastYear(-4);
//
//        String currentDateStr=getCurrentDate();
//        int day=15;// 指定每个月固定还款日
//        String startDateTime="2022-04-01";
//        String endDateTime="2023-05-31";
//        BigDecimal capitalDec = new BigDecimal("100");
//        System.out.println(capitalDec.doubleValue());
//        String loadDate="";
        //LoanRateCount.debx(capitalDec,0.049,false,startDateTime,day,endDateTime);

//        LoanRateCount.equivalentCapital(capitalDec,0.01,false,startDateTime,day,endDateTime);

//        JSONObject jsonObject2=  LoanRateUtilsNew.oneTimeRepayment(capitalDec,0.049,false,startDateTime,endDateTime);

//        JSONObject jsonObject3=  LoanRateCount.expireRepaymentCapital(capitalDec,"quarter",0.05,false,startDateTime,day,endDateTime);

    }





    /**
     * 获取指定年月的最后一天
     * @param year 指定的年
     * @param month 指定的月
     * @return
     */
    public  static String givenMonthLastday(int year,int month){
        LocalDate firstDayOfCurrentDate = LocalDate.of(year, month, 1);
        LocalDate lastDayOfCurrentDate = firstDayOfCurrentDate.with(TemporalAdjusters.lastDayOfMonth());
        return lastDayOfCurrentDate.toString();
    }

    public static String timestampConvertDateTime(long timestamp){
        Date date = new Date(timestamp);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = sdf.format(date);
        return formattedDate;
    }
}
